
if (typeof jQuery === 'undefined') {
    throw new Error('jquery.input JavaScript requires jQuery');
}

if (typeof Plugin === 'undefined') {
    throw new Error('jquery.input JavaScript requires Plugin');
}


(function () {
    'use strict';

    var Button = function (el, options) {
        this.$el = $(el);
        this.namespace = _config_.button.namespace;
        this.defaults = _config_.button.defaults;
        this.methods = _config_.button.methods;
        this.events = _config_.button.events;

        if (this.$el.prop('tagName') === 'BUTTON') {
            this.defaults.type = this.$el.prop('type').toUpperCase();
        } else {
            this.defaults.type = this.$el.prop('tagName').toUpperCase();
        }

        if (this.defaults.type === 'SUBMIT') {
            this.defaults.type = 'POST';
        }

        if (this.$el.prop('tagName') === 'BUTTON' && this.$el.prop('type').toUpperCase() === 'SUBMIT') {
            this.$el.attr('type', 'submit');
        } else {
            this.$el.attr('type', 'button');
        }

        this.getForm();
        //input 初始值合并form元素值, 默认值, 和input元素值
        this.initials = $.com.getDataBindFromElement(this.$el);
        var button = _config_.button.Actions[this.initials.button] || _config_.button.Actions.default;
        this.initials = $.extend(true, {}, _config_.button.initials, button, this.initials);
        this.originals = $.extend(true, {}, this.defaults, this.initials);
        this.originals.type = this.originals.type.toUpperCase();
        this.originals.side = this.originals.side.toLowerCase();
        this.originals.label = this.originals.label || this.$el.text();
        this.originals.enterPress = this.originals.enterPress || false;
        this.$el.attr('data-enter-press', this.originals.enterPress);
        this.options = $.extend(true, {}, this.originals, options);
        this.options.serial = $.com.getSerial(16);
        //父级弹出框
        this.$popup = this.$el.parents(_config_.selector.popupWindow);
        //处理id
        this.getNamedPrefix('name');
        this.$template = $(this.options.template).children();
        this.button = this.options.button;
        this.init();
        this.options.el = this;
    };

    Button.prototype = new Plugin();

    Button.prototype.init = function () {
        this.initButton();
        this.initEvent();
    };

    Button.prototype.initButton = function () {
        if (!$.com.hasValue(this.options.url) && $.com.isJqueryObject(this.$form)) {
            var form = this.$form.data(_config_.form.namespace);
            if ($.com.hasValue(form)) {
                this.options.url = form.options.url;
            }
        }

        this.execute(this.options.loading);

        if (this.options.authorize) {
            this.onAuthorization();
        }

        if (this.options.button !== _config_.button.Actions.default.name) {
            if (this.options.withGroup) {
                var that = this;
                if ($.com.hasValue(this.options.url) && this.options.side === 'server') {
                    //download or export list from server
                    var downloadListClass = $('#__TemplateDownloadList').children().attr('class');
                    this.$el.addClass(downloadListClass);
                    this.$el.empty();
                    $.api.get(this.options.url, function (d) {
                        d = $.com.dataAdapter(d);
                        if ($.com.isArray(d)) {
                            for (var i = 0; i < d.length; i++) {
                                var btn = '<button type="button" ' + _config_.attribute.button + '="download" data-url="' + d[i].Path + '">' + d[i].Name + '</button>';
                                var $button = $(btn);
                                $button.addClass('btn btn-sm waves-effect waves-light btn-default');
                                that.$el.append($button);
                            }

                            that.$el.children().button();
                        }
                    });
                } else {
                    //download or export list from client
                    var $template = $('#__TemplateButtonGroup').children().clone();
                    this.$el.addClass($template.attr('class'));
                    var $button = $template.children('button');
                    $button.addClass(this.options.class);
                    $button.html(this.$template.clone());
                    $button.children('.button-label').html(this.options.label);
                    $button.children('.caret').css('display', 'inline-block');
                    if ($.com.hasValue(this.options.icon)) {
                        $button.children('.button-icon').addClass(this.options.icon);
                    }

                    var $content = $template.children('ul.dropdown-menu').empty();
                    this.$el.append($template.children());
                    this.$el.children().not($content).not($button).each(function () {
                        var $this = $(this);
                        var $li = $('<li></li>');
                        $content.append($li);
                        if ($this.is('.divider')) {
                            $li.addClass('divider');
                        } else {
                            $li.append($this);
                            $this.attr('data-button', that.options.button);
                            $this.button();
                        }
                    });
                }
            } else if (!$.com.isJqueryObject(this.$el.parents('[data-with-group="true"]'))) {
                if ($.com.isJqueryObject(this.$template)) {
                    this.$el.html(this.$template.clone());
                    if ($.com.hasValue(this.options.class)) {
                        this.$el.addClass('btn btn-sm waves-effect waves-light');
                        this.$el.addClass(this.options.class);
                        //title = "编辑" aria- label="编辑"
                        if ($.com.hasValue(this.options.title)) {
                            this.$el.attr({ 'title': this.options.title, 'aria-label': this.options.title });
                        }
                    }
                    if ($.com.hasValue(this.options.label)) {
                        this.$el.children('.button-label').html(this.options.label);
                    } else {
                        this.$el.children('.button-label').remove();
                        this.$el.css('box-shadow', 'inherit');
                    }
                    this.$el.children('.caret').remove();
                    if ($.com.hasValue(this.options.icon)) {
                        this.$el.children('.button-icon').addClass(this.options.icon);
                    } else {
                        this.$el.children('.button-icon').remove();
                    }
                }

                if (this.options.button === 'import') {
                    this.$el.children('.button-input').attr('data-button', this.options.button).attr('data-field', this.options.id).attr('data-label', this.options.label).input();
                    this.$el.children('.k-widget.k-upload').hide();
                }
            }
        }

        this.execute(this.options.loaded);
    };

    Button.prototype.initEvent = function () {
        if (!this.options.withGroup) {
            var that = this;
            this.$el.click(function (event) {
                that.onClick(event);
                event.stopPropagation();
            });

            if (this.options.button === 'upload') {
                this.$el.off('change', ':file').on('change', ':file', function (event) {
                    that.onChange(event);
                });
            }
        }
    };

    Button.prototype.display = function (arg) {
        this.options.display = $.com.hasValue(arg) ? arg : this.options.display;
        if ($.com.hasValue(this.options.display) && !!this.options.display) {
            this.$el.show();
        } else {
            this.$el.hide();
        }
    };

    Button.prototype.destroy = function () {
        var formData = this.$form.data(_config_.form.namespace);
        if ($.com.hasValue(formData) && formData.$buttons.hasValue()) {
            formData.$buttons.removeItem(this.$el);
        }

        this.$el.removeData(_config_.button.namespace);
        this.$el.remove();
    };

    Button.prototype.onClick = function (event) {
        var args = {};
        this.getForm();

        //现在前置事件只需返回 false 就可以阻止事件继续执行
        var ret = this.execute(this.options.clicking, event, args);
        if ($.com.hasValue(ret) && ret === false) {
            return;
        }

        if ($.com.hasValue(this.options.button) && $.com.hasValue(this.options.action)) {
            var actions = this.options.action.replace(/\,\ ?/, ',').split(',');
            if ($.com.isArray(actions)) {
                var that = this;
                for (var i = 0; i < actions.length; i++) {
                    var action = that[actions[i]];
                    if ($.isFunction(action)) {
                        action.apply(that, [event, args]);
                    }
                }
            }
        }

        this.execute(this.options.clicked, event, args);
    };

    Button.prototype.onChange = function (event) {
        //现在前置事件只需返回 false 就可以阻止事件继续执行
        var ret = this.execute(this.options.changeing, event);
        if ($.com.hasValue(ret) && ret === false) {
            return;
        }

        this.execute(this.options.changed, event);
    };

    Button.prototype.onLink = function () {
        if ($.com.hasValue(this.options.url)) {
            var linkUrl = this.options.url;
            if ($.com.isArray(this.options.data)) {
                linkUrl += '?' + this.options.textField + '=' + this.options.data[0][this.options.valueField];
            }

            location.href = linkUrl;
        }
    };

    Button.prototype.onClear = function () {
        if ($.com.isJqueryObject(this.$form)) {
            var form = this.$form.data(_config_.form.namespace);
            form.clear();
        }
    };

    Button.prototype.onReset = function () {
        if ($.com.isJqueryObject(this.$form)) {
            var form = this.$form.data(_config_.form.namespace);
            form.reset();
        }
    };

    Button.prototype.onAddForm = function (event, args) {
        if ($.com.isJqueryObject(this.$form)) {
            this.$form.form('addForm', args);
        }
    };

    Button.prototype.onRemoveForm = function (event, args) {
        if ($.com.isJqueryObject(this.$form)) {
            this.$form.form('removeForm', args);
        }
    };

    Button.prototype.onQuery = function () {
        if ($.com.isJqueryObject(this.$form)) {
            var form = this.$form.data(_config_.form.namespace);
            if ($.com.hasValue(form)) {
                if (!$.com.isJqueryObject(this.$grid)) {
                    this.$grid = $(this.options.grid || _config_.selector.default);
                    if (!this.$grid.hasValue()) {
                        this.$grid = form.$grid;
                        if (!this.$grid.hasValue()) {
                            this.$grid = $(form.options.grid);
                        }
                    }
                }

                if (this.$grid.hasValue()) {
                    var grid = this.$grid.data(_config_.grid.namespace);
                    if ($.com.hasValue(grid)) {
                        form.getQueryExpression();
                        var dataSource = $.com.getDataSource(grid.role);
                        dataSource = $.com.getQueryOptions(dataSource, form.options.dataSource);
                        if ($.com.hasValue(dataSource)) {
                            dataSource.page = 1;
                            dataSource.autoQuery = true;
                            grid.role.dataSource.query(dataSource);
                            grid.resize();
                            grid.initEvent();
                        }
                    }
                }

                var $advancedSearch = form.$buttons.filter('[data-button="advancedSearch"]').first();
                if ($.com.isJqueryObject($advancedSearch)) {
                    if (this.options.autoShrink) {
                        var $target = $($advancedSearch.attr('data-target'));
                        if ($.com.hasValue($target)) {
                            $target.slideUp({ speed: 'slow' });
                        }
                    }

                    $.com.advancedSearchColorful($advancedSearch);
                }
            }
        }
    };

    Button.prototype.onAdvancedSearch = function (event) {
        var $target = $(this.options.target);
        if ($.com.hasValue($target)) {
            var that = this;
            $target.slideToggle({ speed: 'slow' });
            $target.addClass('col-md-12');
            $.com.resizeAdvancedSearch(this.$el);

            $(document).find('.body-content').one("click", function () {
                $target.slideUp({ speed: 'slow' });
                $.com.advancedSearchColorful(that.$el);
                //折叠后执行查询在保存了查询条件情况下不好用
                //that.onQuery();
            });

            event.stopPropagation();

            if (!$target.is(':hidden')) {
                $target.click(function (ev) {
                    ev.stopPropagation();
                });
            }

            $target.attr('tabindex', 0).keypress(function (ev) {
                if (ev.keyCode === 13) {
                    $target.slideUp({ speed: 'slow' });
                    $.com.advancedSearchColorful(that.$el);
                    that.onQuery();
                }
            });
        }
    };

    Button.prototype.onApproved = function () {
        //var $input = this.$form.find('[data-toggle="form"][data-field="ApprovingSuggestion"]');
        //if ($.com.isJqueryObject($input)) {
        //    $input.val('approved').change();
        //}
    };

    Button.prototype.onReject = function () {
        //var $input = this.$form.find('[data-toggle="form"][data-field="ApprovingSuggestion"]');
        //if ($.com.isJqueryObject($input)) {
        //    $input.val('rejected').change();
        //}
    };

    Button.prototype.onUpload = function () {
    };

    Button.prototype.onDownload = function () {
        app.download(this.options.filePath || this.options.url, this.options.fileName);
    };

    Button.prototype.onImport = function (event) {
        if ($.com.hasValue(this.options.fileName) && $.com.hasValue(this.originals.url)) {
            this.options.url = this.originals.url + (this.originals.url.includes('?') ? '&' : '?') + 'fileName=' + this.options.fileName;
            $.api.post(this.options);
        } else {
            var $input = this.$el.find('input:file[id]');
            if ($input.hasValue() && !$input.equal(event.target)) {
                $input.click();
            }
        }
    };

    Button.prototype.onExport = function () {
        if ($.com.hasValue(this.options.url)) {
            var downloadForm = $('#__DownloadForm');
            downloadForm.empty();
            if (this.options.type === this.$el.prop('tagName').toUpperCase()) {
                this.options.type = 'GET';
            }

            downloadForm.attr('method', this.options.type || 'GET');
            var queryString = $.com.getQueryString(this.options.url);
            if ($.com.hasValue(queryString) && $.com.hasValue(queryString.url)) {
                this.$grid = $(this.options.grid || _config_.selector.default);
                if (!$.com.isJqueryObject(this.$grid) && $.com.isJqueryObject(this.$form)) {
                    var form = this.$form.data(_config_.form.namespace);
                    if ($.com.hasValue(form)) {
                        this.$grid = form.$grid;
                        if (!this.$grid.hasValue()) {
                            this.$grid = $(form.options.grid);
                        }
                    }
                }

                if (this.$grid.hasValue()) {
                    var grid = this.$grid.data(_config_.grid.namespace);
                    if ($.com.hasValue(grid)) {
                        var ds = $.com.getDataSource(grid.role);
                        if ($.com.hasValue(form.options.dataSource)) {
                            ds = $.com.getQueryOptions(ds, form.options.dataSource);
                        }
                        if ($.com.hasValue(ds)) {
                            if (!$.com.isArray($.com.getValue(ds, 'filter.filters'))) {
                                if ($.com.isNullOrEmpty(ds.filter)) {
                                    ds.filter = { filters: [] };
                                } else {
                                    ds.filter = { filters: [ds.filter] };
                                }
                            }

                            ds = kendo.data.transports['odata-v4'].parameterMap(ds, 'read');
                            if ($.com.hasValue(ds.$orderby)) {
                                queryString.$orderby = ds.$orderby;
                            }
                            if ($.com.hasValue(ds.$filter)) {
                                queryString.$filter = ds.$filter;
                            }

                            queryString = $.extend(queryString, $.com.getValue(ds, 'transport.read.data'));
                        }
                    }
                }

                var url = queryString.url;
                var has = url.includes('?');
                url += has ? '&' : '?';
                if ($.com.hasValue(queryString.$select)) {
                    url += '$select=' + queryString.$select;
                }

                has = url.includes('?');
                url += has ? '&' : '?';
                if ($.com.hasValue(queryString.$expand)) {
                    url += '$expand=' + queryString.$expand;
                }

                downloadForm.attr('action', url);
                $.each(queryString, function (k, v) {
                    if (k !== 'url') {
                        var arg = '<input type="hidden" name="' + k + '" value="' + v + '" />';
                        downloadForm.append(arg);
                    }
                });

                downloadForm.submit();
            }
        }
    };

    Button.prototype.onSubmit = function () {
        if ($.com.isJqueryObject(this.$form)) {
            var form = this.$form.data(_config_.form.namespace);
            if (!$.com.isNullOrEmpty(form) && (this.options.button === 'delete' || this.options.button === 'get' || form.validate(this.options.validator) !== false)) {
                this.options.data = form.getFormData();

                this.options.type = (this.options.type || 'POST').toUpperCase();

                if ($.com.hasValue(this.options.url)) {

                    //现在前置事件只需返回 false 就可以阻止事件继续执行
                    var ret = this.execute(this.options.beforeSubmit);
                    if ($.com.hasValue(ret) && ret === false) {
                        return;
                    }

                    $.api.ajax(this.options);
                }
            }
        }
    };

    Button.prototype.onAuthorization = function () {
        if ($.com.hasValue(this.options.functionid) || $.isFunction(this.options.authorizeMethod)) {
            var that = this;

            var serverAuthorize = function (functionid) {
                $.api.get('/api/Common/AuthorizationFunction/' + functionid, function (d) {
                    that.execute(that.options.authorizeComplete, d);
                    if (d) {
                        that.options.isAuthenticated = true;
                        that.$el.show();
                    } else {
                        that.options.isAuthenticated = false;
                        that.$el.attr('isAuthenticated', false);
                        that.destroy();
                    }
                });
            };

            var result = false;
            if ($.isFunction(this.options.authorizeMethod)) {
                result = this.execute(this.options.authorizeMethod, $.com.getFormData(this.$form))
            }

            if (this.options.authorizeLogic === 'and') {
                if (result && $.com.hasValue(this.options.functionid)) {
                    serverAuthorize(this.options.functionid);
                } else {
                    this.options.isAuthenticated = false;
                    this.$el.attr('isAuthenticated', false);
                    //this.destroy();
                }
            } else if (this.options.authorizeLogic === 'or') {
                if (!result) {
                    if ($.com.hasValue(this.options.functionid)) {
                        serverAuthorize(this.options.functionid);
                    } else {
                        this.options.isAuthenticated = false;
                        this.$el.attr('isAuthenticated', false);
                        //this.destroy();
                    }
                } else {
                    this.options.isAuthenticated = true;
                    this.$el.show();
                }
            }
        }
    };

    Button.prototype.onAttachmentDownload = function () {
        var $buttons = this.$el.closest('.k-upload-status');
        if ($.com.isJqueryObject($buttons)) {
            this.options.url = $buttons.attr('data-path');
            this.options.fileName = $buttons.attr('data-file-name');
            if ($.com.hasValue(this.options.url)) {
                this.onDownload();
            }
        }
    };

    Button.prototype.getForm = function () {
        //form 取 data-form 指定元素或者 第一个被标记为 data-toggle="form" 的父元素
        var $form = this.$form;
        this.$form = this.$el.attr(_config_.attribute.formAttr);
        if ($.com.hasValue(this.$form)) {
            this.$form = $(this.$form).first();
        } else {
            this.$form = this.$el.parents(_config_.selector.form).first();
        }

        if ($.com.isJqueryObject(this.$form) && $.com.isJqueryObject($form) && !this.$form.equal($form)) {
            var form = $form.data(_config_.form.namespace);
            if ($.com.hasValue(form) && $.com.isJqueryObject(form.$buttons)) {
                form.$buttons.removeItem(this.$el);
            }

            form = this.$form.data(_config_.form.namespace);
            if ($.com.hasValue(form)) {
                form.$buttons.push(this.$el[0]);
            }
        }
    };

    //plug-in
    $.fn.button = function (options) {
        var value = undefined;
        var args = Array.prototype.slice.call(arguments, 1);
        this.each(function () {
            var $this = $(this);
            var data = $this.data(_config_.button.namespace);

            if ($.com.isNullOrEmpty(data)) {
                data = new Button(this, typeof options === 'object' && options);
                $this.data(_config_.button.namespace, data);
            }

            if (typeof options === 'string') {
                //if options is not a method
                if ($.inArray(options, data.methods) < 0) {
                    throw 'Unknown method: ' + options;
                }

                //if options is a plugin method, to execute
                value = data[options].apply(data, args);
            }
        });

        return typeof value === 'undefined' ? this : value;
    };
})(jQuery);